終於進入正題啦!
不論是現實世界還是網路上,小朋友看到東西都喜歡碰一下摸一下(手賤),只要能互動就會興奮到一個不行,特別是能開開關關的東西,一不小心就會被玩壞家長就要來賠錢,還好,我們做的是網頁。
最常遇到的功能無非就是 Drawre / Modal / Dialog / Accordion / Animaiton 任何你想到需要狀態來切換開關的通通都用得到,今天就來刻個 useToogle 吧!
useToggle 無非就是開關,切換 true
與 false
之間,非常簡單。
我們需要:
state
toggle
之後的 DEMO 會使用 Chakra-UI 的元件來搭配我們自己刻的 Hook 一同產出
嘗試最低限度的試玩 Remix 以及 mdx 來產出 demo-site 以及文件
藉這個機會接觸不同的東西來提(ㄋㄩㄝˋ)升(ㄉㄞˋ)自己 (/‵Д′)/~ ╧╧
最常見到的就是一顆按鈕打開一個小框框的功能:
function Example() {
return (
<>
<Button/>
<Modal />
</>
)
}
Button 與 Modal 都是 Chakra-UI的元件,上面的 code 縮減很多內容,只要知道會有一顆按鈕跟一個Modal就好 XD
按照需求,需要一個 useState,並 return 相關的內容:
function useToggle() {
const [state, setState] = useState(false)
return [state, toggle]
}
//如果你想要 return object 也可以
return {state, toggle}
切換用的 toggle
:
const toggle = () => setState((prev) => !prev)
整體會是這樣:
function useToggle(defaultState = false) {
const [state, setState] = useState(defaultState)
const toggle = () => setState((prev) => !prev)
return [state, toggle]
}
function Example() {
const [isOpen, toggle] = useToggle()
return (
<>
<Button onClick={toggle}>TOGGLE</Button>
<Modal isOpen={isOpen} onClose={toggle} isCentered>
<ModalOverlay />
<ModalContent>
<ModalHeader>Hello (´・ω・`)</ModalHeader>
<ModalCloseButton />
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={toggle}>
Close
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
)
}
<Button />
用來打開 Modal<Modal />
本身接受 isOpen 來告訴它要不要打開<Modal />
本身也接受 onClose 來觸發關掉的動作<Button />
也是觸發關掉的動作這樣一來就完成啦!
function useToggle(defaultState = false) {
const [state, setState] = useState(defaultState)
//略
}
function useToggle(defaultState = false) {
if(typeof defaultState !== 'boolean') {
throw new Error("UseToggle: defaultState should be Boolean")
}
const [state, setState] = useState(defaultState)
const toggle = () => setState((prev) => !prev)
return [state, toggle]
}
function useToggle(defaultState = false) {
if(typeof defaultState !== 'boolean') {
throw new Error("UseToggle: defaultState should be Boolean")
}
const [state, setState] = useState(defaultState)
const toggle = useCallback(() => setState((prev) => !prev),[])
return [state, toggle]
}
其實還沒完,儘管一開始我們知道接下來狀態一定會變 true (or false),但這樣的 toggle 乍看下其實很難知道要從什麼狀態變成什麼狀態,而且未來也不確定會不會再塞幾百行的code 與 side effect(?),下一篇再來進一步擴充吧!